package top.yqingyu.trans$client.api;


import top.yqingyu.common.qydata.DataMap;
import top.yqingyu.qymsg.*;
import top.yqingyu.common.utils.UUIDUtil;
import top.yqingyu.common.utils.YamlUtil;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

public class ConnectionConfig {
    public final String CLIENT_USER_ID = UUIDUtil.randomUUID().toString2();
    public final AtomicBoolean RUNNING = new AtomicBoolean(true);
    public volatile String AC_STR = "okkkko";
    public String HEART_BEAT = "HEART_BEAT";
    public String HOST = "127.0.0.1";
    public int PORT = 4729;
    public int PORT2 = 4730;
    public int PORT3 = 4731;
    public DataMap loginData = new DataMap();

    public int radix = 32;
    public volatile int BODY_LENGTH_MAX = 65536 * 100;
    //以下时间为毫秒
    public volatile int PARTITION_CLEAN_TIME = 30 * 60 * 1000;
    public volatile int HEADER_BODY_INTERVAL = 50;

    public volatile int LOGIN_TIMEOUT = 9000;   //登陆超时时间
    public volatile int MSG_TIMEOUT = 5000;   //消息超时时间
    public volatile int HEART_BEAT_TIME = 15000;   //心跳时间
    public volatile int MSG_DEAL_TIME = 10;   //消息接收发送线程时间间隔
    public Type type = Type.INSTANCE;

    public enum Type {
        FILE, //配置文件读取。
        INSTANCE //创建固定实例。
    }

    public volatile boolean pooling = true;

    public volatile short pool_max = 10;
    public volatile short pool_min = 2;
    public volatile long keep_live_time = 3600 * 24;

    public final LinkedBlockingQueue<QyMsg> Main_PartitionMsgQueue = new LinkedBlockingQueue<>();
    public final LinkedBlockingQueue<QyMsg> REQ_MSG_QUEUE = new LinkedBlockingQueue<>();
    public final LinkedBlockingQueue<QyMsg> RSP_MSG_QUEUE = new LinkedBlockingQueue<>();

    public QyMsg AC_MSG = new QyMsg(MsgType.AC, DataType.OBJECT);
    public QyMsg NORMAL_MSG = new QyMsg(MsgType.NORM_MSG, DataType.KRYO5);
    public QyMsg HEART_BEAT_MSG = new QyMsg(MsgType.HEART_BEAT, DataType.STRING);

    public volatile String DEFAULT_DOWNLOAD_PATH = System.getProperty("user.dir");

    public volatile MsgTransfer msgTransfer;

    private ConnectionConfig() {
    }


    public static class Builder {
        private final ConnectionConfig cfg;

        public Builder(Type type) {
            cfg = new ConnectionConfig();
            if (Type.FILE.equals(type)) {
                loadFile(cfg);
            }
        }

        public ConnectionConfig build() {
            cfg.msgTransfer = MsgTransfer.init(cfg.radix, cfg.BODY_LENGTH_MAX);
            cfg.HEART_BEAT_MSG.setFrom(cfg.CLIENT_USER_ID);
            cfg.HEART_BEAT_MSG.putMsg(cfg.HEART_BEAT);
            cfg.AC_MSG.setFrom(cfg.CLIENT_USER_ID);
            cfg.AC_MSG.putMsg(cfg.AC_STR);
            cfg.NORMAL_MSG.setFrom(cfg.CLIENT_USER_ID);
            return cfg;
        }

        private void loadFile(ConnectionConfig cfg) {
            YamlUtil client_yml = YamlUtil.loadYaml("client", YamlUtil.LoadType.BOTH);
            DataMap client = client_yml.getDataMap("trans_client.yml").getData("client");

            cfg.AC_STR = client.getString("ac_str");
            cfg.HEART_BEAT = client.getString("heart_beat");

            cfg.HOST = client.getString("host");
            cfg.PORT = client.getData("main").getIntValue("port");
            cfg.PORT2 = client.getData("sc").getIntValue("port");
            cfg.PORT3 = client.getData("cs").getIntValue("port");

            cfg.BODY_LENGTH_MAX = client.getData("main").getIntValue("body-length-max");
            cfg.PARTITION_CLEAN_TIME = client.getData("cs").getDataMap("msg").getIntValue("partition-clean-time");
            cfg.HEADER_BODY_INTERVAL = client.getData("cs").getDataMap("msg").getIntValue("header-body-interval");

            DataMap time_set = client.getData("main").getData("time_set");
            cfg.LOGIN_TIMEOUT = time_set.getIntValue("login_timeout");
            cfg.MSG_TIMEOUT = time_set.getIntValue("msg_timeout");
            cfg.HEART_BEAT_TIME = time_set.getIntValue("heart_beat_time");
            cfg.MSG_DEAL_TIME = time_set.getIntValue("msg_deal_time");
            cfg.DEFAULT_DOWNLOAD_PATH = client.getString("def-download-path", System.getProperty("user.dir"));
        }


        public Builder AC_STR(String AC_STR) {
            cfg.AC_STR = AC_STR;
            return this;
        }

        public Builder HEART_BEAT(String HEART_BEAT) {
            cfg.HEART_BEAT = HEART_BEAT;
            return this;
        }

        public Builder HOST(String HOST) {
            cfg.HOST = HOST;
            return this;
        }

        public Builder PORT(int PORT) {
            cfg.PORT = PORT;
            return this;
        }

        public Builder PORT2(int PORT2) {
            cfg.PORT2 = PORT2;
            return this;
        }

        public Builder PORT3(int PORT3) {
            cfg.PORT3 = PORT3;
            return this;
        }

        public Builder LoginData(DataMap loginData) {
            cfg.loginData = loginData;
            return this;
        }

        public Builder BODY_LENGTH_MAX(int BODY_LENGTH_MAX) {
            cfg.BODY_LENGTH_MAX = BODY_LENGTH_MAX;
            return this;
        }

        public Builder PARTITION_CLEAN_TIME(int PARTITION_CLEAN_TIME) {
            cfg.PARTITION_CLEAN_TIME = PARTITION_CLEAN_TIME;
            return this;
        }

        public Builder HEADER_BODY_INTERVAL(int HEADER_BODY_INTERVAL) {
            cfg.HEADER_BODY_INTERVAL = HEADER_BODY_INTERVAL;
            return this;
        }

        public Builder LOGIN_TIMEOUT(int LOGIN_TIMEOUT) {
            cfg.LOGIN_TIMEOUT = LOGIN_TIMEOUT;
            return this;
        }

        public Builder MSG_TIMEOUT(int MSG_TIMEOUT) {
            cfg.MSG_TIMEOUT = MSG_TIMEOUT;
            return this;
        }

        public Builder HEART_BEAT_TIME(int HEART_BEAT_TIME) {
            cfg.HEART_BEAT_TIME = HEART_BEAT_TIME;
            return this;
        }

        public Builder MSG_DEAL_TIME(int MSG_DEAL_TIME) {
            cfg.MSG_DEAL_TIME = MSG_DEAL_TIME;
            return this;
        }

        public Builder Type(Type type) {
            cfg.type = type;
            return this;
        }

        public Builder Pooling(boolean pooling) {
            cfg.pooling = pooling;
            return this;
        }

        public Builder Radix(int radix) {
            cfg.radix = radix;
            return this;
        }

        public Builder Pool_max(int pool_max) {
            cfg.pool_max = (short) pool_max;
            return this;
        }

        public Builder Pool_min(int pool_min) {
            cfg.pool_min = (short) pool_min;
            return this;
        }

        public Builder Keep_live_time(long keep_live_time) {
            cfg.keep_live_time = keep_live_time;
            return this;
        }

        public Builder DEFAULT_DOWNLOAD_PATH(String DEFAULT_DOWNLOAD_PATH) {
            cfg.DEFAULT_DOWNLOAD_PATH = DEFAULT_DOWNLOAD_PATH;
            return this;
        }
    }
}
